#ifndef XN_SERIAL_H
#define XN_SERIAL_H
#include <termios.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#ifndef B0
#define B0       0000000
#define B50      0000001
#define B75      0000002
#define B110     0000003
#define B134     0000004
#define B150     0000005
#define B200     0000006
#define B300     0000007
#define B600     0000010
#define B1200    0000011
#define B1800    0000012
#define B2400    0000013
#define B4800    0000014
#define B9600    0000015
#define B19200   0000016
#define B38400   0000017
#define B57600   0010001
#define B115200  0010002
#define B230400  0010003
#define B460800  0010004
#define B500000  0010005
#define B576000  0010006
#define B921600  0010007
#define B1000000 0010010
#define B1152000 0010011
#define B1500000 0010012
#define B2000000 0010013
#define B2500000 0010014
#define B3000000 0010015
#define B3500000 0010016
#define B4000000 0010017
#endif

class CXnSerial
{
public:
	enum Parity
    {
        NONE = 0,
        ODD,
        EVEN
    };

public:
    CXnSerial();
    ~CXnSerial();

public:
    /**
    <pre>
    pDeviceName := /dev/ttyX (unix) | COMx (Windows) 
    iSpeed      := B50 ... B4000000                                    
    iBlock      := 0 | 1 (bool)    是否阻塞方式 在win下该参数无效                                      
    iRtscts     := 0 | 1 (bool)                                        
    iBits       := 7 | 8 (unix) | 4-8 (Windows)                        
    iStopBits   := 1 | 2                                               
    iParity     := CXnSerial::NONE | CXnSerial::ODD | CXnSerial::EVEN     
    return == 0  success, return < 0 error
    </pre>           
    */
    int openDevice(const char *pDeviceName, int iSpeed = B9600, int iBlock = 1, int iRtscts = 0, int iBits = 8, int iStopBits = 1, int iParity = CXnSerial::NONE);
	int openDeviceAgain(const char *pDeviceName);
	int closeDevice();    
    int readChar();
	int readBlock(unsigned char *pBuf, int iLen, int iTimeout = -1);
    int writeChar(unsigned char uchar);   
    int writeBlock(const unsigned char *pBuf, int iLen);
    int readLine(unsigned char *pBuf, int iMaxLen, int iTimeout = 1000);

private:
	int select(int iTimeout = 500); // 设置超时时间  返回0 超时，其他未超时

private:
    int m_iSpeed;
    int m_iBlock;
    int m_iRtscts;
    int m_iBits;
    int m_iStopBits;
    int m_iParity;
    struct termios m_resetCommCfg; 
    int m_fdSerial;
    struct timeval timout;
};

#endif
